<?php
namespace App\Service\CommodityService;
use App\Service\AppService\SystemCacheConfigService;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Model\CommodityModel\SupplierCompany;
use Hyperf\DbConnection\Db;
use App\Model\CommodityModel\SupplierCommodity;
use Hyperf\Utils\WaitGroup;

/**
 * 拉取京东开普勒供应商商品
 * @author hj
 */
class SupplierCommodityJdkeplerPullLogService extends BaseService 
{
    const PULL_FLAG = 'shopjdkepler';
    const TIME_WAIT = 60;//分钟
    const PULL_USER_COUNT = 10;//每次同时拉取供应商的数量
    
    /**
     * 开启计划任务
     */
    public function runTask()
    {
        $config = SystemCacheConfigService::instance()->getCacheInfoBySystemCode('channel_task_user_limit');
        if (empty($config)) {
            return Normal::returnCode(Normal::FAIL, '参数未配置');
        }
        //所有供应商拉取完成间隔时间
        $SupplierPullWaitTime = self::TIME_WAIT;
        
        //预计下次拉取商品时间
        $nextPeriod = date("Y-m-d H:i:s", time() + $SupplierPullWaitTime * 60);
        
        //供应商拉取标签
        $reult_query = SupplierCommodityPullLogService::instance()->getWaitPullSupplierWareHouseInfosByThirdPartyPlatformCode(self::PULL_FLAG);
        if( $reult_query['code'] != Normal::SUC ) {
            return $reult_query;
        }
        $supplierList = $reult_query['data'];

        //开始协助并发拉取
        $count = count($supplierList);
        $wg = new WaitGroup();
        $wg->add($count);
        foreach ($supplierList as $supplier)
        {
            co(function () use ($supplier,$nextPeriod,$wg)
            {
                $this->querySingleSupplierGoods($supplier,$nextPeriod);
                $wg->done();
            });
        }
        $wg->wait();
        return Normal::returnCode(Normal::SUC, '拉取完成');
    }
    
    /**
     * 查询单个供应商
     * @param array $supplier
     */
    public function querySingleSupplierGoods(array $supplier,string $nextPeriod)
    {
        //获取供应商参数
        $company_code           = $supplier['ThirdPartyPlatformCode'] ? $supplier['ThirdPartyPlatformCode'] : $supplier['SupplierCode'];
        $supplierID             = $supplier['SupplierID'];
        $startTime              = microtime(true);
        
        //解析仓库参数
        $apiBody                = $supplier['JsonBody'];
        $routerClass            = '\\App\\Service\\OrderService\\OrderRouteService\\' . ucfirst($company_code);
        
        //获取商品总数
        $count = SupplierCommodity::instance()->where('SupplierCompanyID',$supplierID)->count();
        //初始化拉取状态
        $updateArr = [
            'CommodityGetTaskStatus'    => 0,
            'CommodityGetTotal'         => $count,
            'CommodityGetFinishCount'   => 0,
            'CommodityGetFinishUseTime' => 0.000,
        ];
        SupplierCompany::instance()->where('ID', $supplierID)->update($updateArr);
        //处理分类拉取情况
        $commodityGetTotal = 0;
        $currentPage       = 1;
        $scrollId          = 0;
        while (true)
        {
        
            $rows = SupplierCommodity::instance()->select([
                'ID',
                'SupplierCommoditySkuCode',
            ])
            ->where('ID','>',$scrollId)
            ->where('SupplierCompanyID',$supplierID)
            ->orderBy('ID','ASC')
            ->limit(20)
            ->get()
            ->toArray();
            if( empty($rows) ) 
            {
                break;
            }
            
            //根据分类获取商品
            $queryBody = [
                'skuIds' => array_column($rows,'SupplierCommoditySkuCode'),
            ];
        
            $resQuery = $routerClass::instance()->queryGoodsList(['apiBody'   => $apiBody, 'queryBody' => $queryBody]);
            if ($resQuery['code'] != Normal::SUC) {
                SupplierCompany::instance()->where('ID', $supplierID)->update(['CommodityGetContents' => $resQuery['msg'], 'CommodityGetTaskStatus' => 3]);
                break;
            }
        
            SupplierCompany::instance()->where('ID', $supplierID)->update(['CommodityGetContents' => $resQuery['msg']]);
            
            //动态更新已拉取的数据
            $pull_count = count($resQuery['data']);
            if( $pull_count > 0)
            {
                $commodityGetTotal += $pull_count;
                $updateArr = [
                    'CommodityGetTaskStatus'    => 1,
                    'CommodityGetFinishCount'   => Db::raw("CommodityGetFinishCount + ".$pull_count)
                ];
                SupplierCompany::instance()->where('ID', $supplierID)->update($updateArr);
                $MessageBody  = [
                    'SupplierID'        => $supplierID,
                    'SupplierCode'      => $company_code,
                    'IsFirstPage'       => $currentPage == 1 ? 1 : 0,
                    'DataPage'          => $currentPage,
                    'IsLastPage'        => 0,
                    'GoodsItemList'     => $resQuery['data']
                ];
                SupplierCommodityPullLogService::instance()->publish($MessageBody);
            }
        
            $endRow         = end($rows);
            $scrollId       = $endRow['ID'];
            $currentPage    ++;
        }
        
        //更新总数量
        $MessageBody  = [
            'SupplierID'        => $supplierID,
            'SupplierCode'      => $company_code,
            'IsFirstPage'       => 0,
            'DataPage'          => 1,
            'IsLastPage'        => 1,
            'GoodsItemList'     => []
        ];
        SupplierCommodityPullLogService::instance()->publish($MessageBody);
        
        //拉取完成
        $updateArr = [
            'CommodityGetTaskStatus'    => 2,
            'CommodityGetContents'      => '拉取完成',
            'CommodityGetFinishUseTime' => bcsub((string)microtime(true), $startTime, 3),
            // 'CommodityGetNetPeriod'     => $nextPeriod
            'CommodityGetNetPeriod'     => date("Y-m-d H:i:s", time() + self::TIME_WAIT * 60)
        ];
        SupplierCompany::instance()->where('ID', $supplierID)->update($updateArr);
    }
}